package com.ruoyi.energy.service.impl;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.energy.domain.NyCheckSum;
import com.ruoyi.energy.domain.NyMeterAccount2;
import com.ruoyi.energy.domain.vo.NyCheckSumVO;
import com.ruoyi.energy.mapper.NyCheckSumMapper;
import com.ruoyi.energy.mapper.NyMeterAccount2Mapper;
import com.ruoyi.energy.mapper.NyMeterAccountMapper;
import com.ruoyi.energy.service.INyCheckSumService;
import com.ruoyi.omp.api.domain.NyCheckMeter;
import com.ruoyi.omp.api.domain.NyMeterAccount;
import com.ruoyi.omp.api.enums.NyMeterCategoryEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 私汇总Service业务层处理
 *
 * @author cjie
 * @date 2021-11-06
 */
@Service
public class NyCheckSumServiceImpl implements INyCheckSumService {
    @Autowired
    private NyCheckSumMapper nyCheckSumMapper;

    @Autowired
    private NyMeterAccountMapper nyMeterAccountMapper;

    @Autowired
    private NyMeterAccount2Mapper nyMeterAccount2Mapper;

    /**
     * 查询私汇总
     *
     * @param id 私汇总ID
     * @return 私汇总
     */
    @Override
    public NyCheckSum selectNyCheckSumById(String id) {
        return nyCheckSumMapper.selectNyCheckSumById(id);
    }

    /**
     * 查询私汇总列表
     *
     * @param nyCheckSum 私汇总
     * @return 私汇总
     */
    @Override
    public List<NyCheckSum> selectNyCheckSumList(NyCheckSum nyCheckSum) {
        return nyCheckSumMapper.selectNyCheckSumList(nyCheckSum);
    }

    /**
     * 新增私汇总
     *
     * @param nyCheckSum 私汇总
     * @return 结果
     */
    @Override
//    public int insertNyCheckSum(NyCheckSum nyCheckSum) {
//        nyCheckSum.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
//        nyCheckSum.setCreateTime(DateUtils.getNowDate());
//        nyCheckSum.setCreateBy(SecurityUtils.getUsername());
//        return nyCheckSumMapper.insertNyCheckSum(nyCheckSum);
//    }

    public String insertNyCheckSum(NyCheckSum nyCheckSum) {
        nyCheckSum.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
        nyCheckSum.setCreateTime(DateUtils.getNowDate());
        nyCheckSum.setCreateBy(SecurityUtils.getUsername());
        nyCheckSumMapper.insertNyCheckSum(nyCheckSum);
        return nyCheckSum.getId();
    }

    @Transactional
    public int insertComputeLog(NyCheckSumVO result) {
        NyCheckSum nyCheckSum = new NyCheckSum();
        BeanUtils.copyBeanProp(nyCheckSum,result);
        nyCheckSum.setPid("0");
        String id = this.insertNyCheckSum(nyCheckSum);
        for(NyCheckSumVO acess:result.getChildren()){
            NyCheckSum nyCheckSum1 = new NyCheckSum();
            BeanUtils.copyBeanProp(nyCheckSum1,acess);
            nyCheckSum1.setPid(id);
            String id1 = this.insertNyCheckSum(nyCheckSum1);
            for(NyCheckSumVO node:acess.getChildren()){
                NyCheckSum nyCheckSum2 = new NyCheckSum();
                BeanUtils.copyBeanProp(nyCheckSum2,node);
                nyCheckSum2.setPid(id1);
                this.insertNyCheckSum(nyCheckSum2);
            }
        }
        return 1;
    }

    @Override
    public NyCheckSumVO selectRootById(String id) {
        return nyCheckSumMapper.selectRootById(id);
    }

    @Override
    public List<NyCheckSumVO> selectNyCheckSumVOList(NyCheckSum nyCheckSum) {
        List<NyCheckSum> searchs = this.selectNyCheckSumList(nyCheckSum);
        List<NyCheckSumVO> results = new ArrayList<NyCheckSumVO>();
        for(NyCheckSum search :searchs){
            results.add(this.selectRootById(search.getId()));
        }
        return results;
    }

    @Override
    public int insertComputeLogs(List<NyCheckSumVO> nyCheckSumVOs) {
        int result =0;
        for(NyCheckSumVO nyCheckSumVO:nyCheckSumVOs){
            result += this.insertLogAndShare(nyCheckSumVO);
        }
        return result;
    }

    private int insertLogAndShare(NyCheckSumVO result) {
        NyCheckSum nyCheckSum = new NyCheckSum();
        BeanUtils.copyBeanProp(nyCheckSum,result);
        //nyCheckSum.setPid("0");
        //nyCheckSum.setIsComputed("1");
        //String id = this.insertNyCheckSum(nyCheckSum);
        nyCheckSumMapper.insertNyCheckSum(nyCheckSum);
        for(NyCheckSumVO acess:result.getChildren()){
            NyCheckSum nyCheckSum1 = new NyCheckSum();
            BeanUtils.copyBeanProp(nyCheckSum1,acess);
            //nyCheckSum1.setPid(id);
            //nyCheckSum1.setIsComputed("1");
            //String id1 = this.insertNyCheckSum(nyCheckSum1);
            nyCheckSumMapper.insertNyCheckSum(nyCheckSum1);
            for(NyCheckSumVO node:acess.getChildren()){
                NyCheckSum nyCheckSum2 = new NyCheckSum();
                BeanUtils.copyBeanProp(nyCheckSum2,node);
                //nyCheckSum2.setPid(id1);
                //nyCheckSum2.setPid("1");
                nyCheckSumMapper.insertNyCheckSum(nyCheckSum2);
            }
        }
        //更新分摊池
        NyMeterAccount2 nyMeterAccount = nyMeterAccount2Mapper.selectNyMeterAccount2ById(nyCheckSum.getMeterId());
        nyMeterAccount.setShareInitialValue(nyMeterAccount.getShareInitialValue().add(nyCheckSum.getDiffValue()));
        nyMeterAccount2Mapper.updateNyMeterAccount2(nyMeterAccount);
        return 1;
    }

    /**
     * 修改私汇总
     *
     * @param nyCheckSum 私汇总
     * @return 结果
     */
    @Override
    public int updateNyCheckSum(NyCheckSum nyCheckSum) {
        return nyCheckSumMapper.updateNyCheckSum(nyCheckSum);
    }

    /**
     * 批量删除私汇总
     *
     * @param ids 需要删除的私汇总ID
     * @return 结果
     */
    @Override
    public int deleteNyCheckSumByIds(String[] ids) {
        //查询 ids,汇总， 总表，
        NyCheckSum result=null;
        for(String id:ids){
            result = nyCheckSumMapper.selectNyCheckSumById(id);
            if(result.getCategory() == NyMeterCategoryEnum.总表.getCode()){
                //更新分摊池,减少累加
                NyMeterAccount nyMeterAccount = nyMeterAccountMapper.selectNyMeterAccountById(result.getMeterId());
                nyMeterAccount.setShareInitialValue(nyMeterAccount.getShareInitialValue().subtract(result.getDiffValue()));
                nyMeterAccountMapper.updateNyMeterAccount(nyMeterAccount);
            }
        }
        return nyCheckSumMapper.deleteNyCheckSumByIds(ids);
    }

    /**
     * 删除私汇总信息
     *
     * @param id 私汇总ID
     * @return 结果
     */
    @Override
    public int addNyCheckSumByIds(String[] ids) {
        //修改为累加，累加到分摊池；
        int result = 0;
        for(String id:ids){
            NyCheckSum nyCheckSum = nyCheckSumMapper.selectNyCheckSumById(id);
            NyMeterAccount nyMeterAccount = nyMeterAccountMapper.selectNyMeterAccountById(nyCheckSum.getMeterId());
            nyMeterAccount.setShareInitialValue(nyMeterAccount.getShareInitialValue().add(nyCheckSum.getDiffValue()));
            nyMeterAccountMapper.updateNyMeterAccount(nyMeterAccount);
            nyCheckSum.setIsComputed("1");
            result += this.updateComputedState(nyCheckSum);
        }
        return result;
    }

    private int updateComputedState(NyCheckSum nyCheckSum){
        int reuslt = nyCheckSumMapper.updateNyCheckSum(nyCheckSum);
        //首先查出当前节点是否存在子节点，如果存在，则遍历删除子节点
        List<NyCheckSum> nyCheckSumList=nyCheckSumMapper.selectNyCheckSumByParentId(nyCheckSum.getId());
        //递归查出所有的子节点，List为null是递归结束条件，速度有点慢，暂且这样吧
        if(nyCheckSumList!=null&&nyCheckSumList.size()>0){
            for (NyCheckSum child:nyCheckSumList){
                child.setIsComputed(nyCheckSum.getIsComputed());
                updateComputedState(child);
            }
        }
        return reuslt;
    }


    @Override
    public NyCheckSum selectNyCheckSum(NyCheckMeter nyCheckMeter) {
        NyCheckSum nyCheckSum = new NyCheckSum();
        BeanUtils.copyBeanProp(nyCheckSum,nyCheckMeter);
        //nyCheckSum.set
        List<NyCheckSum> nyCheckSums = nyCheckSumMapper.selectNyCheckSumList(nyCheckSum);
        if(nyCheckSums != null && nyCheckSums.size()>0){
            return nyCheckSums.get(0);
        }
        return null;
    }
}
